package com.konka.spring.framework.webmvc.servlet;

import com.konka.spring.framework.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author konka
 * @date 2023/2/10
 * @description:
 */
public class HandlerAdapter {

    /**
     * 根据路由找到具体要执行的方法，反射调用，包括参数传递
     * @param req
     * @param resp
     * @param handlerMapping
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public ModelAndView handle(HttpServletRequest req, HttpServletResponse resp,HandlerMapping handlerMapping) throws InvocationTargetException, IllegalAccessException {
        Method method = handlerMapping.getMethod();
        //存放参数对应的下标
        Map<String,Integer> paramIndexMapping = new HashMap<>();
        //解析要执行方法的参数
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];
            String key = parameter.getName();
            if (parameter.isAnnotationPresent(RequestParam.class)){
                RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
                String paramAlias = requestParam.value();
                if (paramAlias != null && !"".equals(paramAlias)){
                    key = paramAlias;
                }
            }else if (parameter.getType().equals(HttpServletRequest.class)
                    || parameter.getType().equals(HttpServletResponse.class)){
                key = parameter.getType().getSimpleName();
            }
            paramIndexMapping.put(key,i);
        }

        //按照要执行方法的参数顺序，放置的参数值数组
        Object[] paramValues = new Object[parameters.length];
        //获取请求中的参数,解析后放到paramValues中
        Map<String,String[]> parameterMap = req.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            String[] paramValueArray = entry.getValue();
            //TODO 这里暂时只能处理String类型的参数
            //去除参数中的"["、"]" 和 多空格
            String value = Arrays.toString(paramValueArray).replaceAll("\\[|\\]", "").replaceAll("\\s", "");
            if (!paramIndexMapping.containsKey(entry.getKey())){continue;}
            Integer index = paramIndexMapping.get(entry.getKey());
            paramValues[index] = value;
        }
        //处理特殊参数HttpServletRequest、HttpServletResponse
        if (paramIndexMapping.containsKey("HttpServletRequest")){
            paramValues[paramIndexMapping.get("HttpServletRequest")] = req;
        }
        if (paramIndexMapping.containsKey("HttpServletResponse")){
            paramValues[paramIndexMapping.get("HttpServletResponse")] = resp;
        }

        Object result = method.invoke(handlerMapping.getController(), paramValues);
        if (result == null || result instanceof Void){return null;}
        boolean isModelAndView = handlerMapping.getMethod().getReturnType() == ModelAndView.class;
        if (isModelAndView){
            return (ModelAndView) result;
        }
        return null;
    }
}
